﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.Xml.XPath;
using System.Xml.Xsl;
using System.Xml;
using System.Text;
using System.Xml.Linq;
using System.Web.UI;
using System.Reflection;
using System.Web.UI.WebControls;
using SharingCenter.Web.Shared;
using System.Web.Security;

namespace SharingCenter.Web.Classes
{
    public class ContextConversion
    {
        public static string GetTransformedXml(Stream contextXml, string appName, string xsltFileName, string eventName, Guid eventRaiserId, string lastUpdate)
        {
            string appKey = appName + "_" + eventName;
            string result = string.Empty;
            bool useApp = false;

            if (HttpContext.Current.Application[appKey] != null && useApp)
            {
                result = (string)HttpContext.Current.Application[appKey];
            }
            else
            {
                // load XML from file
                StreamReader sr = new StreamReader(contextXml);
                XPathDocument myXPathDoc = new XPathDocument(sr);

                // load XSL from file
                XslCompiledTransform xslt = new XslCompiledTransform();
                string xsltPath = HttpContext.Current.Server.MapPath(string.Format(@"~/Mod/{0}/{1}", appName, xsltFileName));
                xslt.Load(xsltPath);

                //string cacheKey = FormsAuthentication.HashPasswordForStoringInConfigFile(xsltPath, "MD5");
                //if (null == HttpContext.Current.Application["M_" + cacheKey])
                //{
                //    HttpContext.Current.Application["M_" + cacheKey] = xslt;
                //}
                //else
                //{
                //    xslt = (XslCompiledTransform)HttpContext.Current.Application["M_" + cacheKey];
                //}

                XsltArgumentList xslArg = new XsltArgumentList();
                xslArg.AddParam("relrootpath", "", HttpRuntime.AppDomainAppVirtualPath == "/" ? "" : HttpRuntime.AppDomainAppVirtualPath);
                xslArg.AddParam("eventname", "",  eventName );
                xslArg.AddParam("userid", "", eventRaiserId.ToString());
                xslArg.AddParam("lastupdate", "", lastUpdate);
                

                // memory stream that will hold the transformation
                MemoryStream htmlOutput = new MemoryStream();

                XmlWriterSettings settings = new XmlWriterSettings();
                settings.OmitXmlDeclaration = true;
                settings.ConformanceLevel = ConformanceLevel.Fragment;
                settings.Encoding = Encoding.UTF8;

                // XML Writter user to write to the memory stream
                using (XmlWriter writterOut = XmlWriter.Create(htmlOutput, settings))
                {

                    // run the ransformation
                    xslt.Transform(myXPathDoc, xslArg, writterOut);

                    // make sure everything gets pushed to the memory stream
                    writterOut.Flush();

                    // go to the start of the memory stream
                    htmlOutput.Position = 0;

                    // read from the memory stream
                    StreamReader strm = new StreamReader(htmlOutput, Encoding.UTF8);

                    // read the stream to text reader
                    using (TextReader txtRead = strm)
                    {
                        result = txtRead.ReadToEnd();
                    }

                    HttpContext.Current.Application[appKey] = result;
                }
            }

            return result;
        }

        public static void TransformControls(ref XElement contentToRender, Page page)
        {
            try
            {
                List<XElement> ctrlList = contentToRender.Descendants("control").ToList();
                foreach (XElement c in ctrlList)
                {
                    string renderedHtml = string.Empty;
                    switch (c.Attribute("kind").Value.ToLower())
                    {
                        case "usercontrol":
                            break;
                        case "userlink":
                            renderedHtml = RenderUserLink(c);
                            break;
                        case "useravatar":
                            renderedHtml = RenderUserAvatar(c/*, ref page*/);
                            break;
                        case "servercontrol":
                            break;
                    }

                    c.ReplaceWith(XElement.Parse(renderedHtml));
                }
            }
            catch { }
        }

        public static string RenderUserLink(XElement c)
        {
            Guid userId = new Guid(c.Attribute("UserId").Value);
            NickNameLink lnk = new NickNameLink();
            lnk.UserId = userId;

            StringBuilder sb = new StringBuilder();
            StringWriter tw = new StringWriter(sb);
            HtmlTextWriter hw = new HtmlTextWriter(tw);
            lnk.RenderControl(hw);

            return sb.ToString();
        }

        public static string RenderUserAvatar(XElement e/*, ref Page page*/)
        {
            /*
            string controlPath = "~/Shared/ThumbAvatar.ascx";
            ThumbAvatar avatar = (ThumbAvatar)page.LoadControl(controlPath);
            avatar.UserId = new Guid(e.Attribute("UserId").Value);
            if (e.Attribute("ShowNickName") != null)
            {
                avatar.ShowNickName = Convert.ToBoolean(e.Attribute("ShowNickName").Value);
            }
            StringBuilder sb = new StringBuilder();
            StringWriter tw = new StringWriter(sb);
            HtmlTextWriter hw = new HtmlTextWriter(tw);

            avatar.RenderControl(hw);
            return sb.ToString();*/

            return string.Format("<div class='avtb' sn='false'><span class='uid' title='{0}'></span></div>", e.Attribute("UserId").Value);
        }

        string RenderUserControl(XElement e, Type t, ref Page page)
        {
            string controlPath = string.Format("~/{0}/{1}", e.Attribute("location").Value, e.Attribute("name").Value);
            Control control = page.LoadControl(controlPath);
            
            foreach (XElement p in e.Descendants("property"))
            {
                string attrName = p.Attribute("name").Value;
                PropertyInfo info = t.GetProperty(attrName);

                object value;
                if (p.Attribute("type").Value == "System.Guid")
                {
                    value = new Guid(p.Attribute("value").Value);
                }
                else
                {
                    Type valueType = Type.GetType(p.Attribute("type").Value);
                    value = Convert.ChangeType(p.Attribute("value").Value, valueType);
                }

                info.SetValue(control, value, null);
            }

            StringBuilder sb = new StringBuilder();
            StringWriter tw = new StringWriter(sb);
            HtmlTextWriter hw = new HtmlTextWriter(tw);

            control.RenderControl(hw);
            return sb.ToString();
        }
    }
}
